package com.xinyue.game.center.business.account;

import com.xinyue.game.center.business.account.logic.AccountManager;
import com.xinyue.game.center.business.account.param.AccountLoginRequest;
import com.xinyue.game.center.business.account.param.AccountLoginResponse;
import com.xinyue.game.center.common.ServerErrorCode;
import com.xinyue.game.center.config.GameCenterConfig;
import com.xinyue.game.center.dao.AccountDao;
import com.xinyue.game.center.dao.entity.AccountEntity;
import com.xinyue.game.utils.token.GameToken;
import com.xinyue.game.utils.token.TokenManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.time.Duration;

/**
 * @Author 王广帅
 * @Date 2021/5/23 21:09
 */
@Service
public class AccountService {
    @Autowired
    private AccountManager accountManager;
    @Autowired
    private AccountDao accountDao;
    @Autowired
    private GameCenterConfig gameCenterConfig;

    private TokenManager<GameToken> tokenManager;

    @PostConstruct
    public void init() {
        tokenManager = new TokenManager(gameCenterConfig.getTokenAesKey());
    }

    public AccountEntity login(AccountLoginRequest loginParam) {
        accountManager.checkUsername(loginParam.getUsername());
        accountManager.checkPassword(loginParam.getPassword());
        AccountEntity account = accountDao.findByUsername(loginParam.getUsername());
        checkAccountExist(account, loginParam);
        return account;
    }

    /**
     * 创建token
     *
     * @param userId 用户id
     * @return
     */
    private String createToken(String userId) throws Exception {
        GameToken userToken = new GameToken();
        userToken.setUserId(userId);
        long nowTime = System.currentTimeMillis();
        userToken.setCreateTime(nowTime);
        Duration periodTime = Duration.ofDays(gameCenterConfig.getTokenPeriodDay());
        long endTime = nowTime + periodTime.toMillis();
        userToken.setEndTime(endTime);
        return tokenManager.createToken(userToken);
    }

    public AccountLoginResponse getLoginResponse(AccountEntity account) throws Exception {
        AccountLoginResponse loginResponse = new AccountLoginResponse();
        loginResponse.setUserId(account.getId());
        loginResponse.setUsername(account.getUsername());
        loginResponse.setRegisterTime(account.getRegisterTime());
        loginResponse.setSectionPlayerMap(account.getSectionPlayerMap());
        String token = this.createToken(account.getId());
        loginResponse.setToken(token);
        return loginResponse;
    }

    private void checkAccountExist(AccountEntity account, AccountLoginRequest loginParam) {
        if (account == null) {
            throw ServerErrorCode.ACCOUNT_1006.exception();
        }
        if (!account.getPassword().equals(loginParam.getPassword())) {
            throw ServerErrorCode.ACCOUNT_10087.exception();
        }
    }

    public AccountEntity getAndCheckAccount(String userId) {
        AccountEntity accountEntity = accountDao.findById(userId).orElseThrow(() -> ServerErrorCode.ACCOUNT_1006.exception());
        return accountEntity;
    }

    public void updateAccount(AccountEntity accountEntity) {
        accountDao.save(accountEntity);
    }
}
